package com.example.springboottest.example.javassist.dynamic;

import javassist.*;

/**
 * Java 字节码以二进制的形式存储在 class 文件中，每一个 class 文件包含一个 Java 类或接口。Javaassist 就是一个用来处理 Java 字节码的类库。
 * <p>
 * Javassist是一个开源的分析、编辑和创建Java字节码的类库。
 * <p>
 * 1、ClassPool
 * ClassPool：一个基于哈希表（Hashtable）实现的CtClass对象容器，其中键名是类名称，
 * 值是表示该类的CtClass对象（Hashtable和Hashmap类似都是实现map接口，hashmap可以接收null的值，但是Hashtable不行）。
 * <p>
 * 2、CtClass
 * CtClass表示类，一个CtClass(编译时类）对象可以处理一个class文件，这些CtClass对象可以从ClassPoold的一些方法获得。
 * <p>
 * 3、CtMethod
 * CtMethod：表示类中的方法。
 * <p>
 * 4、CtConstructor
 * CtConstructor的实例表示一个构造函数。它可能代表一个静态构造函数（类初始化器）。
 * <p>
 * 5、ClassClassPath
 * 该类作用是用于通过 getResourceAsStream（） 在 java.lang.Class 中获取类文件的搜索路径。
 */
public class dynamicJavassistMain {
    public static void main(String[] args) throws Exception {
        //给某类的方法动态增强
        dynamicAdd();
    }

    /**
     * 动态增加某方法功能
     */
    public static void dynamicAdd() throws Exception {
        ClassPool cp = ClassPool.getDefault();//在默认系统搜索路径获取ClassPool对象。
        CtClass cc = cp.get("com.example.springboottest.example.javassist.dynamic.SimpleImpl");  //获取SimpleImpl类的
        CtMethod m = cc.getDeclaredMethod("say"); //获取hello类的say方法
        m.insertBefore("{System.out.println(\"欢迎你：\" + $1);}");//在正文的开头插入字节码
        m.insertAfter("{ System.out.println(\"再见: \" + $1); }");//在正文的结尾插入字节码

        Class c = cc.toClass();//将此类转换为java.lang.Class对象
        //反射创建对象并进行强转,这个并没有重新生成类
        SimpleImpl h = (SimpleImpl) c.newInstance();
        h.say("tom");//        调用方法say
    }
}
